package com.idea.relax.redis.support.utils;

import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * @className: RelaxUtil
 * @description:
 * @author: salad
 * @date: 2022/5/28
 **/
public class RelaxUtil {

	public static final String COLON = ":";

	public static final String EMPTY = "";

	public static final String LEFT_BRACE = "{";

	public static final String RIGHT_BRACE = "}";

	public static final String $LEFT_BRACE = "${";


	/**
	 * 对象组中是否存在 Empty Object
	 *
	 * @param os 对象组
	 * @return boolean
	 */
	public static boolean hasEmpty(Object... os) {
		for (Object o : os) {
			if (isEmpty(o)) {
				return true;
			}
		}
		return false;
	}

	public static boolean isEmpty(Object obj) {
		if (obj == null) {
			return true;
		} else if (obj instanceof Optional) {
			return !((Optional<?>) obj).isPresent();
		} else if (obj instanceof CharSequence) {
			return ((CharSequence) obj).length() == 0;
		} else if (obj.getClass().isArray()) {
			return Array.getLength(obj) == 0;
		} else if (obj instanceof Collection) {
			return ((Collection<?>) obj).isEmpty();
		} else {
			return obj instanceof Map && ((Map) obj).isEmpty();
		}
	}

	public static boolean isNotEmpty(Object obj) {
		return !isEmpty(obj);
	}

	public static boolean isBlank(final CharSequence cs) {
		return !StringUtils.hasText(cs);
	}

	public static boolean isNotBlank(final CharSequence cs) {
		return StringUtils.hasText(cs);
	}

	public static boolean eq(final CharSequence v1, final CharSequence v2) {
		return eq(v1, v2, false);
	}

	public static boolean eqIgnoreCase(final CharSequence v1, final CharSequence v2) {
		return eq(v1, v2, true);
	}

	public static boolean eq(CharSequence str1, CharSequence str2, boolean ignoreCase) {
		if (null == str1) {
			return str2 == null;
		} else if (null == str2) {
			return false;
		} else {
			return ignoreCase ? str1.toString()
				.equalsIgnoreCase(str2.toString()) : str1.equals(str2);
		}
	}

	/**
	 * 同 log 格式的 format 规则
	 * <p>
	 * use: format("my name is {}, and i like {}!", "L.cm", "Java")
	 *
	 * @param message   需要转换的字符串
	 * @param arguments 需要替换的变量
	 * @return 转换后的字符串
	 */
	public static String format(@Nullable String message, @Nullable Object... arguments) {
		// message 为 null 返回空字符串
		if (message == null) {
			return EMPTY;
		}
		// 参数为 null 或者为空
		if (arguments == null || arguments.length == 0) {
			return message;
		}
		StringBuilder sb = new StringBuilder((int) (message.length() * 1.5));
		int cursor = 0;
		int index = 0;
		int argsLength = arguments.length;
		for (int start, end; (start = message.indexOf(LEFT_BRACE, cursor)) != -1 && (end = message.indexOf(RIGHT_BRACE, start)) != -1 && index < argsLength; ) {
			sb.append(message, cursor, start);
			sb.append(arguments[index]);
			cursor = end + 1;
			index++;
		}
		sb.append(message.substring(cursor));
		return sb.toString();
	}

	public static boolean startEndWith(String start,String value,String end) {
		return value.startsWith(start) && value.endsWith(end);
	}

	public static <K, V> Map<K, V> toMap(Object... keysValues) {
		return CollectionUtil.toMap(keysValues);
	}

	/**
	 * 将CheckedException转换为UncheckedException.
	 *
	 * @param e Throwable
	 * @return {RuntimeException}
	 */
	public static RuntimeException unchecked(Throwable e) {
		return ExceptionUtil.unchecked(e);
	}

}
